package cn.codingxiaxw.web;

import cn.codingxiaxw.dto.Exposer;
import cn.codingxiaxw.dto.SeckillExecution;
import cn.codingxiaxw.dto.SeckillResult;
import cn.codingxiaxw.entity.Seckill;
import cn.codingxiaxw.entity.UserPhone;
import cn.codingxiaxw.enums.SeckillStatEnum;
import cn.codingxiaxw.exception.RepeatKillException;
import cn.codingxiaxw.exception.SeckillCloseException;
import cn.codingxiaxw.exception.SeckillException;
import cn.codingxiaxw.service.SeckillService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * Created by codingBoy on 16/11/28.
 */
@Controller   //把当前SeckillController放入spring容器中
@RequestMapping("/seckill")//url:模块/资源/{}/细分
public class SeckillController
{
    @Autowired
    private SeckillService seckillService;


    /**
     * 获取秒杀列表
     * @param model
     * @return
     */
    @RequestMapping(value = "/list",method = RequestMethod.GET)
    //可以直接返回modelandview
    //不过建议把model弄成参数，返回jsp页面
    //list.jps(页面) + model（数据） = modelandview
    public String list(Model model)
    {
        //list.jsp+mode=ModelAndView
        //获取列表页
        List<Seckill> list=seckillService.getSeckillList();
        model.addAttribute("list",list);
        return "list";
    }


    /**
     * 获取秒杀详情页
     * @param model
     * @param seckillid
     * @return
     */
    //@RequestMapping(value = "list/{seckillid}", method = RequestMethod.GET)
    @RequestMapping(value = "{seckillid}/detail",method = RequestMethod.GET)
    public String detail(Model model,@PathVariable("seckillid") Long seckillid){
        //如果seckillid为空，则重定向到列表页
        if(seckillid == null){
            return "redirect:/seckill/list";
        }
        Seckill seckill = seckillService.getById(seckillid);

        //如果用户随便填入一个没有的id，查出来数据为空，则转发到，列表页面
        if(seckill == null){
            return "forward:/seckill/list";
        }

        //查到数据放进model，并且转发到detal.jsp
        model.addAttribute("seckill",seckill);
        return "detail";
    }


    //post请求在页面直接敲出来是访问不到的

    /**
     * dto 是web层和service层的数据传递
     * 返回秒杀地址的json数据
     * 定义一个SeckillResult泛型类，用来返回json数据
     * 秒杀判断是否开启，开启则返回秒杀地址，不开启则返回秒杀开启和结束时间
     * @param seckillid
     * @return
     */
    //我的写法
/*    public SeckillResult<Exposer> exposer(Long seckillid){
        SeckillResult<Exposer> exposerSeckillResult = new SeckillResult<Exposer>();
        Exposer exposer = seckillService.exportSeckillUrl(seckillid);
        if (exposer.getMd5() == null){
            return new SeckillResult<Exposer>(false,"秒杀失败，用户非法输入");
        }
        return new SeckillResult<Exposer>(true,exposer);
    }*/

    //视频写法
    //ajax ,json暴露秒杀接口的方法
    @RequestMapping(value = "/{seckillId}/exposer",
            method = RequestMethod.GET,
            produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public SeckillResult<Exposer> exposer(@PathVariable("seckillId") Long seckillId)
    {
        SeckillResult<Exposer> result;
        try{
            Exposer exposer=seckillService.exportSeckillUrl(seckillId);
            result=new SeckillResult<Exposer>(true,exposer);
        }catch (Exception e)
        {
            e.printStackTrace();
            result=new SeckillResult<Exposer>(false,e.getMessage());
        }

        return result;
    }






    /**
     * 执行秒杀
     * userPhone从cookie中获取，把required设置为false，如果没有也不报错。
     * @param seckillId
     * @param md5
     * @param userPhone
     * @return
     */
    @RequestMapping(value = "/{seckillId}/{md5}/execution",
            method = RequestMethod.POST,
            produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public SeckillResult<SeckillExecution> execute(@PathVariable("seckillId") Long seckillId,
                                                   @PathVariable("md5") String md5,
                                                   @CookieValue(value = "userPhone",required = false) Long userPhone)
    {
        //手机号验证
        if (userPhone==null)
        {
            return new SeckillResult<SeckillExecution>(false,"未注册");
        }
        SeckillResult<SeckillExecution> result;

        //需要对SeckillExecution里面的异常进行处理
        try {
            SeckillExecution execution = seckillService.executeSeckill(seckillId, userPhone, md5);
            return new SeckillResult<SeckillExecution>(true, execution);
        }catch (RepeatKillException e1)
        {
            SeckillExecution execution=new SeckillExecution(seckillId, SeckillStatEnum.REPEAT_KILL);
            return new SeckillResult<SeckillExecution>(true,execution);
        }catch (SeckillCloseException e2)
        {
            SeckillExecution execution=new SeckillExecution(seckillId, SeckillStatEnum.END);
            return new SeckillResult<SeckillExecution>(true,execution);
        }
        catch (Exception e)
        {
            SeckillExecution execution=new SeckillExecution(seckillId, SeckillStatEnum.INNER_ERROR);
            return new SeckillResult<SeckillExecution>(true,execution);
        }

    }


    /**
     * 测试接口，手机号作为参数
     * 执行秒杀
     * userPhone从cookie中获取，把required设置为false，如果没有也不报错。
     * @param seckillId
     * @param md5
     * @param userPhone
     * @return
     */
    @RequestMapping(value = "/{seckillId}/{md5}/execution1",
            method = RequestMethod.POST,
            produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public SeckillResult<SeckillExecution> execute1(@PathVariable("seckillId") Long seckillId,
                                                    @PathVariable("md5") String md5,
                                                    @RequestBody UserPhone userPhone)

    {
        Long userPhone1 = userPhone.getUserPhone();
        //手机号验证
        if (userPhone1==null)
        {
            return new SeckillResult<SeckillExecution>(false,"未注册");
        }
        SeckillResult<SeckillExecution> result;

        //需要对SeckillExecution里面的异常进行处理
        try {
            SeckillExecution execution = seckillService.executeSeckill(seckillId, userPhone1, md5);
            return new SeckillResult<SeckillExecution>(true, execution);
        }catch (RepeatKillException e1)
        {
            SeckillExecution execution=new SeckillExecution(seckillId, SeckillStatEnum.REPEAT_KILL);
            return new SeckillResult<SeckillExecution>(true,execution);
        }catch (SeckillCloseException e2)
        {
            SeckillExecution execution=new SeckillExecution(seckillId, SeckillStatEnum.END);
            return new SeckillResult<SeckillExecution>(true,execution);
        }
        catch (Exception e)
        {
            SeckillExecution execution=new SeckillExecution(seckillId, SeckillStatEnum.INNER_ERROR);
            return new SeckillResult<SeckillExecution>(true,execution);
        }

    }

    //获取系统时间
    @RequestMapping(value = "/time/now",method = RequestMethod.GET)
    @ResponseBody
    public SeckillResult<Long> time()
    {
        Date now=new Date();
        return new SeckillResult<Long>(true,now.getTime());
    }



}























